﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Data;
using System.Windows.Forms;

using AtletIS.Shared.Data;
using AtletIS.Shared.Data.aDbDataSetTableAdapters;
using AtletIS.Shared.Entities;

namespace AtletIS.Shared.Helpers
{
    public static class ResultsHelper
    {
        public static bool bResultsWithSplitColumns = false;
        public static bool bResultsWithSplitTable = false;
        public static bool bResultsWithSplitAsDiff = false;

        public static DataTable dtSplitsTable;
        public static PerformancesTableAdapter taPerformances = new PerformancesTableAdapter();

        #region Track

        /// <summary>
        ///  Výsledky pre rozdelenú disciplínu (MultiRunTable)
        /// </summary>
        public static void MultiRun(TreeNode tnDiscipline)
        {
            string htmlFilePath = HtmlHelper.GetNewHtmlFileName("(V) " + tnDiscipline.Parent.Text);
            StreamWriter sw = new StreamWriter(htmlFilePath, false, Encoding.Default);

            try
            {
                ResultsHeader(sw);

                MultiRunTable(tnDiscipline, sw);
                
                ResultsFooter(sw);

                sw.Close();
                sw.Dispose();

                WordHelper.CreateWordFromHtml(htmlFilePath);
            }
            catch (Exception ex)
            {
                if (sw != null)
                {
                    sw.Close();
                    sw.Dispose();
                }

                ExceptionHelper.ShowErrorInfo(ex);
            }
        }

        /// <summary>
        ///  Výsledky pre jednoduchú disciplínu (RunTable)
        /// </summary>
        public static void SingleRun(DisciplineListEntity discipline)
        {
            string htmlFilePath = HtmlHelper.GetNewHtmlFileName("(V) " + discipline.Name);
            StreamWriter sw = new StreamWriter(htmlFilePath, false, Encoding.Default);

            try
            {
                ResultsHeader(sw);

                sw.WriteLine("<h3>" + discipline.Name.ToString() + "</h3>");
                RunTable(sw, discipline);

                ResultsFooter(sw);

                sw.Close();
                sw.Dispose();

                WordHelper.CreateWordFromHtml(htmlFilePath);
            }
            catch (Exception ex)
            {
                if (sw != null)
                {
                    sw.Close();
                    sw.Dispose();
                }

                ExceptionHelper.ShowErrorInfo(ex);
            }
        }

        /// <summary>
        ///  Spája tabuľky výsledkov pre rozdelenú disciplínu (SummaryRunTable + RunTable)
        /// </summary>
        public static void MultiRunTable(TreeNode tnDiscipline, StreamWriter sw)
        {
            DisciplineListEntity parentDiscipline = DisciplineListHelper.ConvertToEntity(DatabaseHelper.GetDisciplineListById(Convert.ToInt32(tnDiscipline.Name)).Rows[0]);

            DataTable dtSubDisciplineList = DatabaseHelper.GetDisciplineListByParentIdActive(parentDiscipline.ID);

            if (!parentDiscipline.IsFinal)
            {
                DataTable dtSummaryPerformances = new DataTable();
                foreach (DataRow drDiscipline in dtSubDisciplineList.Rows)
                {
                    DataTable dtPerformances = DatabaseHelper.GetPerformancesByDisciplineListId(Convert.ToInt32(drDiscipline["ID"]));
                    dtSummaryPerformances.Merge(dtPerformances);
                }

                // Print summary
                sw.WriteLine("<h3>" + tnDiscipline.Parent.Text + " - " + tnDiscipline.Text + " - Celkové poradie" + "</h3>");
                DataTable dtSubdisciplines = DatabaseHelper.GetDisciplineListById(Convert.ToInt32(tnDiscipline.Name)); // taDisciplineList.GetById(Convert.ToInt32(tnDiscipline.Name));
                if (dtSubdisciplines.Rows.Count > 0)
                {
                    DisciplineListEntity subdiscipline = DisciplineListHelper.ConvertToEntity(dtSubdisciplines.Rows[0]);
                    SummaryRunTable(sw, subdiscipline, dtSummaryPerformances);
                }
            }

            // Print disciplines
            foreach (DataRow drDiscipline in dtSubDisciplineList.Rows)
            {
                sw.WriteLine("<h3>" + tnDiscipline.Parent.Text + " - " + drDiscipline["Name"].ToString() + "</h3>");
                DisciplineListEntity discipline = DisciplineListHelper.ConvertToEntity(drDiscipline);
                RunTable(sw, discipline, isChild: true);
            }
        }

        /// <summary>
        ///  Sumárna tabuľka výsledkov pre rozdelenú disciplínu
        /// </summary>
        public static void SummaryRunTable(StreamWriter sw, DisciplineListEntity discipline, DataTable dtPerformances)
        {
            RunTableHeader(sw, discipline);
            int rowCount = 1, prevResult = 0;

            // --- MAIN --- Ranked
            foreach (DataRow dr in dtPerformances.Select("Result > 0 OR (Result = 0 AND Code <> 0)", "Code, Result, SecondaryRank"))
            {
                RunTableRow(sw, rowCount, dr, discipline, rowCount, prevResult);
                prevResult = Convert.ToInt32(dr["Result"]);
                rowCount += 1;
            }

            // --- MAIN --- Unranked
            foreach (DataRow dr in dtPerformances.Select("Result = 0 AND Code = 0", "Code, Result"))
            {
                RunTableRow(sw, 0, dr, discipline, rowCount, prevResult);
                prevResult = Convert.ToInt32(dr["Result"]);
                rowCount += 1;
            }
                        
            sw.WriteLine("</table>");

            PointsHelper.GetPointsTable(discipline, sw);
        }

        /// <summary>
        ///  Tabuľka výsledkov pre jednoduchú disciplínu
        /// </summary>
        private static void RunTable(StreamWriter sw, DisciplineListEntity discipline, bool isChild = false)
        {
            DataTable dtPerformances = DatabaseHelper.GetPerformancesByDisciplineListId(discipline.ID);

            // Naplni tabulku pre stlpce medzicasov v hlavnej tabulke
            if (bResultsWithSplitColumns)
            {
                if (bResultsWithSplitAsDiff)
                    dtSplitsTable = DatabaseHelper.GetChipDataSplitsTableDiff(discipline.ID);
                else
                    dtSplitsTable = DatabaseHelper.GetChipDataSplitsTable(discipline.ID);
            }
            else
            {
                dtSplitsTable = null;
            }
            
            RunTableHeader(sw, discipline);
            int rowCount = 1, prevResult = 0;

            // --- MAIN --- Ranked
            foreach (DataRow dr in dtPerformances.Select("Rank > 0 OR (Rank = 0 AND Code <> 0)", "Code, Rank, SecondaryRank"))
            {
                RunTableRow(sw, Convert.ToInt32(dr["Rank"]), dr, discipline, rowCount, prevResult);
                prevResult = Convert.ToInt32(dr["Result"]);
                rowCount += 1;
            }

            // --- MAIN --- Unranked
            foreach (DataRow dr in dtPerformances.Select("Rank = 0 AND Code = 0", "Code, Rank"))
            {
                RunTableRow(sw, Convert.ToInt32(dr["Rank"]), dr, discipline, rowCount, prevResult);
                prevResult = Convert.ToInt32(dr["Result"]);
                rowCount += 1;
            }

            sw.WriteLine("</table>");

            #region Ext. texts for performances

            if (discipline.Relay)
            {
                ExtTextsHelper.PrintRelayTable(discipline, sw);
            }

            #endregion

            #region Ext. texts for discipline list

            DataTable dtExtTexts = DatabaseHelper.GetExtTextsByDisciplineListIdActive(discipline.ID);
            if (dtExtTexts != null && dtExtTexts.Rows.Count > 0)
            {
                sw.WriteLine("<hr>");
                sw.WriteLine("<table class=\"extra\">");

                foreach (DataRow drExtText in dtExtTexts.Rows)
                {
                    sw.WriteLine("<tr>");
                    sw.WriteLine("  <td width=\"20\"></td>");
                    sw.WriteLine("  <td>" + drExtText["Text1"].ToString() + "</td>");
                    sw.WriteLine("</tr>");
                }

                sw.WriteLine("</table>");
            }

            #endregion

            #region Chip split table

            if (bResultsWithSplitTable && (discipline.DisciplineCode == Globals.LongRunCode | discipline.DisciplineCode == Globals.MarathonCode))
            {
                ChipResultHelper.SplitsTable(discipline, sw, false);
            }

            #endregion

            #region Points table
            
            if (!isChild)
                PointsHelper.GetPointsTable(discipline, sw);

            #endregion

        } 

        /// <summary>
        ///  Hlavičkový riadok tabuľky pre behy
        /// </summary>
        private static void RunTableHeader(StreamWriter sw, DisciplineListEntity discipline)
        {
            sw.WriteLine("<table class=\"main-table\">");
            sw.WriteLine("<tr bgcolor=\"#D8D8D8\">");
            sw.WriteLine("  <th width=\"30\">#          </th>");
            sw.WriteLine("  <th width=\"30\">Št.č.      </th>");
            sw.WriteLine("  <th width=\"30\"></th>");

            if (discipline.Relay)
                sw.WriteLine("  <th>Názov      </th>");
            else
            {
                sw.WriteLine("  <th>Meno      </th>");
                sw.WriteLine("  <th>Nar.       </th> ");
            }
            
            if (Globals.ActiveCompetition.ClubsCountries == true)
                sw.WriteLine("  <th>Klub    </th>");
            else
                sw.WriteLine("  <th>Krajina    </th>");
            sw.WriteLine("  <th width=\"60\">Výkon      </th>");

            if (discipline.DisciplineCode == 1)
            {
                sw.WriteLine("  <th width=\"50\">Reak.</th>");
            }

            sw.WriteLine("  <th width=\"30\"></th>");
            sw.WriteLine("  <th width=\"30\"></th>");

            if (dtSplitsTable != null)
            {
                DataTable dtCheckPoints = DatabaseHelper.GetCheckPointsByDisciplineListId(discipline.ID);

                foreach (DataColumn col in dtSplitsTable.Columns)
                {
                    if ((col.ColumnName != "ID") && (!col.ColumnName.EndsWith("Order")))
                    {
                        if (dtCheckPoints.Select("ID = " + col.ColumnName).Count() >0)
                        {
                            string checkPointName = dtCheckPoints.Select("ID = " + col.ColumnName)[0]["Name"].ToString();
                            sw.WriteLine("  <th>" + checkPointName + "</th>");
                            sw.WriteLine("  <th>#</th>");
                        }
                        else
                        {
                            sw.WriteLine("  <th>" + col.ColumnName + "</th>");
                            sw.WriteLine("  <th>#</th>");
                        }
                    }
                }
            }

            sw.WriteLine("</tr>");
        }

        /// <summary>
        ///  Riadok tabuľky pre behy
        /// </summary>
        private static void RunTableRow(StreamWriter sw, int rank, DataRow dr, DisciplineListEntity discipline, int rowCount, int prevResult)
        {
            PrintHelper.PrintRowHeader(sw, rowCount);

            // Rank
            if (Convert.ToInt32(dr["Code"]) == 0 & Convert.ToInt32(dr["Result"]) != prevResult & rank != 0)
                sw.WriteLine("  <td align=\"center\">" + rank.ToString() + "</td>");
            else
                sw.WriteLine("  <td align=\"center\"></td>");

            // Start number, flag, name, birthdate, club/country
            sw.WriteLine("  <td align=\"center\">" + PrintHelper.PrintStartNumber(dr) + "</td>");
            sw.WriteLine("  <td align=\"center\">" + PrintHelper.PrintFlagImage(dr) + "</td>");

            // Name, Birthdate
            if (discipline.Relay)
            {
                sw.Write("  <td >" + PrintHelper.PrintRelayName(dr, Globals.ActiveCompetition.ClubsCountries) + "</td>");
            }
            else
            {
                sw.WriteLine("  <td>" + PrintHelper.PrintName(dr) + "</td>");
                sw.WriteLine("  <td align=\"center\">" + PrintHelper.PrintBirthdate(Convert.ToDateTime(dr["BirthDate"])) + "</td>");
            }

            // Club / Country
            sw.WriteLine("  <td>" + PrintHelper.PrintClubCountry(Globals.ActiveCompetition.ClubsCountries, dr) + "</td>");

            // Result
            sw.WriteLine("  <td align=\"center\"><b>" + PrintHelper.PrintResultWithCode(Convert.ToInt32(dr["Code"]),
                dr["Result"].ToString(), 
                discipline)  + "</b></td>");

            // Reaction
            if (discipline.DisciplineCode == 1)
                sw.WriteLine("  <td align=\"center\">" + dr["Reaction"].ToString() + "</td>");

            // PB, SB
            sw.WriteLine("  <td align=\"center\">" + PrintHelper.PrintPbSb(discipline.DisciplineCode,
                dr["ResultQuality"].ToString(),
                Convert.ToInt32(dr["Code"]), 
                Convert.ToInt32(dr["Result"]), 
                Convert.ToInt32(dr["PB"]), 
                Convert.ToInt32(dr["SB"])) + "</td>");

            // Points
            sw.WriteLine("  <td align=\"center\">" + PrintHelper.PrintPoints(dr) + "</td>");

            //Split columns
            if (dtSplitsTable != null)
            {
                if (dtSplitsTable.Select("ID = " + dr["ID"].ToString()).Count() > 0)
                {
                    DataRow drSplits = dtSplitsTable.Select("ID = " + dr["ID"].ToString())[0];
                    foreach (DataColumn col in dtSplitsTable.Columns)
                    {
                        if (col.ColumnName != "ID")
                        {
                            if (!col.ColumnName.EndsWith("Order"))
                            {
                                DateTime dtSplitTime = Convert.ToDateTime(drSplits[col.ColumnName]);
                                int splitRank = Convert.ToInt32(drSplits[col.ColumnName + "_Order"]);

                                TimeSpan tsResultTime = new TimeSpan(0, dtSplitTime.Hour, dtSplitTime.Minute, dtSplitTime.Second, dtSplitTime.Millisecond);

                                sw.WriteLine("  <td align=\"center\">" + String.Format("{0:00}:{1:00}:{2:00},{3:00}", tsResultTime.Hours, tsResultTime.Minutes, tsResultTime.Seconds, tsResultTime.Milliseconds / 10).TrimStart('0', ':') + "</td>");
                                sw.WriteLine("  <td align=\"center\">" + splitRank.ToString() + ".</td>");
                            }
                        }
                    }
                }
                
            }
            
            // End of line
            sw.WriteLine("</tr>");
        }

        #endregion

        #region Field

        public static void FieldResults(DisciplineListEntity discipline)
        {
            string htmlFilePath = HtmlHelper.GetNewHtmlFileName("(V) " + discipline.Name);
            StreamWriter sw = new StreamWriter(htmlFilePath, false, Encoding.Default);

            try
            {
                ResultsHeader(sw);

                sw.WriteLine("<h3>" + discipline.Name.ToString() + "</h3>");
                
                switch (discipline.DisciplineCode)
                {
                    case Globals.ThrowsCode:
                        ThrowsTable(sw, discipline);
                        break;

                    case Globals.HorJumpCode:
                        HorJumpsTable(sw, discipline);
                        break;

                    case Globals.VerJumpCode:
                        VerJumpsTable(sw, discipline);
                        break;
                }
                
                ResultsFooter(sw);

                sw.Close();
                sw.Dispose();

                WordHelper.CreateWordFromHtml(htmlFilePath);
            }
            catch (Exception ex)
            {
                if (sw != null)
                {
                    sw.Close();
                    sw.Dispose();
                }

                ExceptionHelper.ShowErrorInfo(ex);
            }
        }

        public static void ThrowsTable(StreamWriter sw, DisciplineListEntity discipline)
        {
            DataTable dtPerformances = DatabaseHelper.GetPerformancesByDisciplineListId(discipline.ID); // taPerformances.GetByDisciplineListId(discipline.ID);

            #region Table header

            sw.WriteLine("<table class=\"main-table\">");
            sw.WriteLine("<tr height=\"30\" bgcolor=\"#D8D8D8\">");
            sw.WriteLine("  <th width=\"30\" >#         </th>");
            sw.WriteLine("  <th width=\"30\">Št.č.      </th>");
            sw.WriteLine("  <th width=\"30\"></th>");
            sw.WriteLine("  <th>Meno      </th>");
            sw.WriteLine("  <th>Nar.      </th> ");
            if (Globals.ActiveCompetition.ClubsCountries == true)
                sw.WriteLine("  <th>Klub  </th>");
            else
                sw.WriteLine("  <th>Krajina  </th>");
            sw.WriteLine("  <th width=\"60\">Výkon     </th>");
            sw.WriteLine("  <th width=\"40\"></th>");
            sw.WriteLine("  <th width=\"40\"></th>");
            sw.WriteLine("</tr>");

            #endregion

            int rowCount = 1, prevRank = 0;

            #region Ranked performances

            foreach (DataRow dr in dtPerformances.Select("Rank > 0 OR (Rank = 0 AND Code <> 0)", "Code, Rank"))
            {
                PrintHelper.PrintRowHeader(sw, rowCount);

                // Rank
                if (Convert.ToInt32(dr["Code"]) == 0 & Convert.ToInt32(dr["Rank"]) != prevRank & Convert.ToInt32(dr["Rank"]) != 0)
                    sw.WriteLine("  <td align=\"center\">" + dr["Rank"].ToString() + "</td>");
                else
                    sw.WriteLine("  <td align=\"center\"></td>");

                sw.WriteLine("  <td align=\"center\">" + PrintHelper.PrintStartNumber(dr) + "</td>");

                // Flag, name, birthdate, club/country
                sw.WriteLine("  <td align=\"center\">" + PrintHelper.PrintFlagImage(dr) + "</td>");
                sw.WriteLine("  <td>" + PrintHelper.PrintName(dr) + "</td>");
                sw.WriteLine("  <td align=\"center\">" + PrintHelper.PrintBirthdate(Convert.ToDateTime(dr["BirthDate"])) + "</td>");
                sw.WriteLine("  <td>" + PrintHelper.PrintClubCountry(Globals.ActiveCompetition.ClubsCountries, dr) + "</td>");

                // Result
                sw.WriteLine("  <td align=\"center\"><b>" + PrintHelper.PrintResultWithCode(Convert.ToInt32(dr["Code"]), dr["Result"].ToString(), discipline) + "</b></td>");

                string resultQuality = PrintHelper.PrintPbSb(discipline.DisciplineCode, dr["ResultQuality"].ToString(), (int)dr["Code"], (int)dr["Result"], (int)dr["PB"], (int)dr["SB"]);
                sw.WriteLine("  <td align=\"center\">" + resultQuality + "</td>");
                sw.WriteLine("  <td align=\"center\">" + PrintHelper.PrintPoints(dr) + "</td>");
                
                sw.WriteLine("</tr>");

                prevRank = Convert.ToInt32(dr["Rank"]);
                rowCount += 1;
            }

            #endregion

            #region Not-ranked performances

            foreach (DataRow dr in dtPerformances.Select("Rank = 0 AND Code = 0", "Code, Rank"))
            {
                PrintHelper.PrintRowHeader(sw, rowCount);

                // Rank
                sw.WriteLine("  <td align=\"center\"></td>");
                sw.WriteLine("  <td align=\"center\">" + PrintHelper.PrintStartNumber(dr) + "</td>");

                // Flag, name, birthdate, club/country
                sw.WriteLine("  <td align=\"center\">" + PrintHelper.PrintFlagImage(dr) + "</td>");
                sw.WriteLine("  <td>" + PrintHelper.PrintName(dr) + "</td>");
                sw.WriteLine("  <td align=\"center\">" + PrintHelper.PrintBirthdate(Convert.ToDateTime(dr["BirthDate"])) + "</td>");
                sw.WriteLine("  <td>" + PrintHelper.PrintClubCountry(Globals.ActiveCompetition.ClubsCountries, dr) + "</td>");

                // Result
                sw.WriteLine("  <td align=\"center\"><b>" + PrintHelper.PrintResultWithCode(Convert.ToInt32(dr["Code"]), dr["Result"].ToString(), discipline) + "</b></td>");
                sw.WriteLine("  <td align=\"center\"></td>");
                sw.WriteLine("  <td align=\"center\"></td>");

                sw.WriteLine("</tr>");

                prevRank = Convert.ToInt32(dr["Rank"]);
                rowCount += 1;
            }

            #endregion

            sw.WriteLine("</table>");

            #region Ext. texts for performances

            DataTable dtExtTexts = ExtTextsHelper.ExtTextsDataTable(discipline);
            if (dtExtTexts.Rows.Count > 0)
            {
                sw.WriteLine("<hr>");

                sw.WriteLine("<table class=\"extra\">");
                sw.WriteLine("<tr>");
                sw.WriteLine("  <td width=\"30\" ></td>");
                sw.WriteLine("  <td width=\"30\" ></td>");
                sw.WriteLine("  <td></td>");
                for (int i = 1; i <= 6; i++)
                {
                    sw.WriteLine("  <td align=\"center\"><b>" + i.ToString() + "</b></td> ");
                }
                sw.WriteLine("</tr>");

                foreach (DataRow dr in dtPerformances.Select("Rank > 0", "Rank"))
                {
                    DataRow[] drExtText = dtExtTexts.Select("PerformanceId = " + dr["ID"]);
                    sw.WriteLine("<tr>");
                    sw.WriteLine("  <td align=\"center\">" + PrintHelper.PrintRank(dr) + "</td>");
                    sw.WriteLine("  <td align=\"center\">" + PrintHelper.PrintStartNumber(dr) + "</td>");
                    sw.WriteLine("  <td>" + PrintHelper.PrintName(dr) + "</td>");
                    try
                    {
                        for (int i = 1; i <= 6; i++)
                        {
                            if (drExtText[0][i.ToString()] != DBNull.Value)
                                sw.WriteLine("  <td align=\"center\">" + PrintHelper.PrintResult(drExtText[0][i.ToString()].ToString(), discipline.DisciplineCode) + "</td>");
                            else
                                sw.WriteLine("<td></td>");
                        }
                    }
                    catch { }
                    sw.WriteLine("</tr>");
                }

                foreach (DataRow dr in dtPerformances.Select("Rank = 0", "Rank"))
                {
                    DataRow[] drExtText = dtExtTexts.Select("PerformanceId = " + dr["ID"]);
                    sw.WriteLine("<tr>");
                    sw.WriteLine("  <td align=\"center\">" + PrintHelper.PrintRank(dr) + "</td>");
                    sw.WriteLine("  <td align=\"center\">" + PrintHelper.PrintStartNumber(dr) + "</td>");
                    sw.WriteLine("  <td>" + PrintHelper.PrintName(dr) + "</td>");
                    try
                    {
                        for (int i = 1; i <= 6; i++)
                        {
                            if (drExtText[0][i.ToString()] != DBNull.Value)
                                sw.WriteLine("  <td align=\"center\">" + PrintHelper.PrintResult(drExtText[0][i.ToString()].ToString(), discipline.DisciplineCode) + "</td>");
                            else
                                sw.WriteLine("<td></td>");
                        }
                    }
                    catch { }
                    sw.WriteLine("</tr>");
                }

                sw.WriteLine("</table>");
            }

            #endregion

            #region Ext. texts for discipline

            dtExtTexts = DatabaseHelper.GetExtTextsByDisciplineListIdActive(discipline.ID);
            if (dtExtTexts.Rows.Count > 0)
            {
                sw.WriteLine("<hr>");
                sw.WriteLine("<table class=\"extra\">");

                foreach (DataRow drExtText in dtExtTexts.Rows)
                {
                    sw.WriteLine("<tr>");
                    sw.WriteLine("  <td width=\"20\"></td>");
                    sw.WriteLine("  <td>" + drExtText["Text1"] + "</td>");
                    sw.WriteLine("</tr>");
                }

                sw.WriteLine("</table>");
            }

            #endregion

            #region Points table

            PointsHelper.GetPointsTable(discipline, sw);

            #endregion

        }

        public static void HorJumpsTable(StreamWriter sw, DisciplineListEntity discipline)
        {
            DataTable dtPerformances = DatabaseHelper.GetPerformancesByDisciplineListId(discipline.ID); // taPerformances.GetByDisciplineListId(discipline.ID);

            #region Table header

            sw.WriteLine("<table class=\"main-table\">");
            sw.WriteLine("<tr height=\"30\" bgcolor=\"#D8D8D8\">");
            sw.WriteLine("  <th width=\"30\">#         </th>");
            sw.WriteLine("  <th width=\"30\">Št.č.      </th>");
            sw.WriteLine("  <th width=\"30\"></th>");
            sw.WriteLine("  <th>Meno      </th>");
            sw.WriteLine("  <th>Nar.      </th> ");
            if (Globals.ActiveCompetition.ClubsCountries == true)
                sw.WriteLine("  <th>Klub  </th>");
            else
                sw.WriteLine("  <th>Krajina  </th>");
            sw.WriteLine("  <th width=\"60\">Výkon     </th>");
            sw.WriteLine("  <th width=\"40\"></th>");
            sw.WriteLine("  <th width=\"40\"></th>");
            sw.WriteLine("</tr>");

            #endregion

            int rowCount = 1, prevRank = 0;

            #region Ranked performances

            foreach (DataRow dr in dtPerformances.Select("Rank > 0 OR (Rank = 0 AND Code <> 0)", "Code, Rank"))
            {
                if (rowCount % 2 == 1)
                    sw.WriteLine("<tr>");
                else
                    sw.WriteLine("<tr bgcolor=\"#CFECEC\">");

                // Rank
                if (Convert.ToInt32(dr["Code"]) == 0 & Convert.ToInt32(dr["Rank"]) != prevRank & Convert.ToInt32(dr["Rank"]) != 0)
                    sw.WriteLine("  <td align=\"center\">" + dr["Rank"].ToString() + "</td>");
                else
                    sw.WriteLine("  <td align=\"center\"></td>");

                sw.WriteLine("  <td align=\"center\">" + PrintHelper.PrintStartNumber(dr) + "</td>");

                // Flag, name, birthdate, club/country
                sw.WriteLine("  <td align=\"center\">" + PrintHelper.PrintFlagImage(dr) + "</td>");
                sw.WriteLine("  <td>" + PrintHelper.PrintName(dr) + "</td>");
                sw.WriteLine("  <td align=\"center\">" + PrintHelper.PrintBirthdate(Convert.ToDateTime(dr["BirthDate"])) + "</td>");
                sw.WriteLine("  <td>" + PrintHelper.PrintClubCountry(Globals.ActiveCompetition.ClubsCountries, dr) + "</td>");

                // Result
                sw.WriteLine("  <td align=\"center\"><b>" + PrintHelper.PrintResultWithCode(Convert.ToInt32(dr["Code"]), dr["Result"].ToString(), discipline) + "</b></td>");

                // PB, SB
                string resultQuality = PrintHelper.PrintPbSb(discipline.DisciplineCode, dr["ResultQuality"].ToString(), (int)dr["Code"], (int)dr["Result"], (int)dr["PB"], (int)dr["SB"]);
                sw.WriteLine("  <td align=\"center\">" + resultQuality + "</td>");
                sw.WriteLine("  <td align=\"center\">" + PrintHelper.PrintPoints(dr) + "</td>");

                sw.WriteLine("</tr>");

                prevRank = Convert.ToInt32(dr["Rank"]);
                rowCount += 1;
            }

            #endregion

            #region Unranked performances

            foreach (DataRow dr in dtPerformances.Select("Rank = 0 AND Code = 0", "Code, Rank"))
            {
                if (rowCount % 2 == 1)
                    sw.WriteLine("<tr>");
                else
                    sw.WriteLine("<tr bgcolor=\"#CFECEC\">");

                // Rank
                sw.WriteLine("  <td align=\"center\"></td>");
                sw.WriteLine("  <td align=\"center\">" + PrintHelper.PrintStartNumber(dr) + "</td>");

                // Flag, name, birthdate, club/country
                sw.WriteLine("  <td align=\"center\">" + PrintHelper.PrintFlagImage(dr) + "</td>");
                sw.WriteLine("  <td>" + PrintHelper.PrintName(dr) + "</td>");
                sw.WriteLine("  <td align=\"center\">" + PrintHelper.PrintBirthdate(Convert.ToDateTime(dr["BirthDate"])) + "</td>");
                sw.WriteLine("  <td>" + PrintHelper.PrintClubCountry(Globals.ActiveCompetition.ClubsCountries, dr) + "</td>");

                // Result
                sw.WriteLine("  <td align=\"center\"><b>" + PrintHelper.PrintResultWithCode(Convert.ToInt32(dr["Code"]), dr["Result"].ToString(), discipline) + "</b></td>");

                // PB, SB
                sw.WriteLine("  <td align=\"center\"></td>");
                sw.WriteLine("  <td align=\"center\"></td>");

                sw.WriteLine("</tr>");

                rowCount += 1;
            }

            #endregion

            sw.WriteLine("</table>");

            #region Ext. texts for performances

            DataTable dtExtTexts = ExtTextsHelper.ExtTextsDataTable(discipline);
            if (dtExtTexts.Rows.Count > 0)
            {
                sw.WriteLine("<hr>");

                sw.WriteLine("<table class=\"extra\">");
                sw.WriteLine("<tr>");
                sw.WriteLine("  <td width=\"30\" ></td>");
                sw.WriteLine("  <td width=\"30\" ></td>");
                sw.WriteLine("  <td></td>");
                for (int i = 1; i <= 6; i++)
                {
                    sw.WriteLine("  <td align=\"center\"><b>" + i.ToString() + "</b></td> ");
                }
                sw.WriteLine("</tr>");

                foreach (DataRow dr in dtPerformances.Select("Rank > 0", "Rank"))
                {
                    DataRow[] drExtText = dtExtTexts.Select("PerformanceId = " + dr["ID"]);
                    sw.WriteLine("<tr>");
                    sw.WriteLine("  <td align=\"center\">" + PrintHelper.PrintRank(dr) + "</td>");
                    sw.WriteLine("  <td align=\"center\">" + PrintHelper.PrintStartNumber(dr) + "</td>");
                    sw.WriteLine("  <td>" + PrintHelper.PrintName(dr) + "</td>");
                    try
                    {
                        for (int i = 1; i <= 6; i++)
                        {
                            if (drExtText[0][i.ToString()] != DBNull.Value)
                            {
                                string line = "  <td align=\"center\">";
                                line += PrintHelper.PrintResult(drExtText[0][i.ToString()].ToString(), discipline.DisciplineCode);
                                if (drExtText[0]["W" + i.ToString()].ToString() != string.Empty)
                                    line += " / " + drExtText[0]["W" + i.ToString()].ToString();
                                line += "</td>";
                                sw.WriteLine(line);
                            }
                            else
                                sw.WriteLine("<td></td>");
                        }
                    }
                    catch { }
                    sw.WriteLine("</tr>");
                }

                foreach (DataRow dr in dtPerformances.Select("Rank = 0", "Rank"))
                {
                    DataRow[] drExtText = dtExtTexts.Select("PerformanceId = " + dr["ID"]);
                    sw.WriteLine("<tr>");
                    sw.WriteLine("  <td align=\"center\">" + PrintHelper.PrintRank(dr) + "</td>");
                    sw.WriteLine("  <td align=\"center\">" + PrintHelper.PrintStartNumber(dr) + "</td>");
                    sw.WriteLine("  <td>" + PrintHelper.PrintName(dr) + "</td>");
                    try
                    {
                        for (int i = 1; i <= 6; i++)
                        {
                            if (drExtText[0][i.ToString()] != DBNull.Value)
                            {
                                string line = "  <td align=\"center\">";
                                line += PrintHelper.PrintResult(drExtText[0][i.ToString()].ToString(), discipline.DisciplineCode);
                                line += "</td>";
                                sw.WriteLine(line);
                            }
                            else
                                sw.WriteLine("<td></td>");
                        }
                    }
                    catch { }
                    sw.WriteLine("</tr>");
                }

                sw.WriteLine("</table>");
            }

            #endregion

            #region Ext. texts for discipline

            dtExtTexts = DatabaseHelper.GetExtTextsByDisciplineListIdActive(discipline.ID); // taExtTexts.GetByDiscListId(discipline.ID);
            if (dtExtTexts.Rows.Count > 0)
            {
                sw.WriteLine("<hr>");
                sw.WriteLine("<table class=\"extra\">");

                foreach (DataRow drExtText in dtExtTexts.Rows)
                {
                    sw.WriteLine("<tr>");
                    sw.WriteLine("  <td width=\"20\"></td>");
                    sw.WriteLine("  <td>" + drExtText["Text1"] + "</td>");
                    sw.WriteLine("</tr>");
                }

                sw.WriteLine("</table>");
            }

            #endregion

            #region Points table

            PointsHelper.GetPointsTable(discipline, sw);

            #endregion
        }   

        public static void VerJumpsTable(StreamWriter sw, DisciplineListEntity discipline)
        {
            discipline = DisciplineListHelper.ConvertToEntity(DatabaseHelper.GetDisciplineListById(discipline.ID).Rows[0]);
            DataTable dtPerformances = DatabaseHelper.GetPerformancesByDisciplineListId(discipline.ID);

            #region Table header

            sw.WriteLine("<table class=\"main-table\">");
            sw.WriteLine("<tr height=\"30\" bgcolor=\"#D8D8D8\">");
            sw.WriteLine("  <th width=\"30\">#       </th>");
            sw.WriteLine("  <th width=\"30\">Št.č.      </th>");
            sw.WriteLine("  <th width=\"30\"></th>");
            sw.WriteLine("  <th>Meno    </th>");
            sw.WriteLine("  <th>Nar.    </th> ");
            if (Globals.ActiveCompetition.ClubsCountries == true)
                sw.WriteLine("  <th>Klub  </th>");
            else
                sw.WriteLine("  <th>Krajina  </th>");
            sw.WriteLine("  <th width=\"60\">Výkon   </th>");
            sw.WriteLine("  <th width=\"40\"></th>");
            sw.WriteLine("  <th width=\"40\"></th>");
            sw.WriteLine("</tr>");

            #endregion

            int rowCount = 1;

            #region Ranked performances

            foreach (DataRow dr in dtPerformances.Select("Rank > 0 OR (Rank = 0 AND Code <> 0)", "Code, Rank"))
            {
                PrintHelper.PrintRowHeader(sw, rowCount);

                // Rank
                if (Convert.ToInt32(dr["Code"]) == 0 && Convert.ToInt32(dr["Rank"]) != 0)
                    sw.WriteLine("  <td align=\"center\">" + dr["Rank"].ToString() + "</td>");
                else
                    sw.WriteLine("  <td align=\"center\"></td>");

                sw.WriteLine("  <td align=\"center\">" + PrintHelper.PrintStartNumber(dr) + "</td>");

                // Flag, name, birthdate, club/country
                sw.WriteLine("  <td align=\"center\">" + PrintHelper.PrintFlagImage(dr) + "</td>");
                sw.WriteLine("  <td>" + PrintHelper.PrintName(dr) + "</td>");
                sw.WriteLine("  <td align=\"center\">" + PrintHelper.PrintBirthdate(Convert.ToDateTime(dr["BirthDate"])) + "</td>");
                sw.WriteLine("  <td>" + PrintHelper.PrintClubCountry(Globals.ActiveCompetition.ClubsCountries, dr) + "</td>");

                // Result
                sw.WriteLine("  <td align=\"center\"><b>" + PrintHelper.PrintResultWithCode(Convert.ToInt32(dr["Code"]), dr["Result"].ToString(), discipline) + "</b></td>");
                
                string resultQuality = PrintHelper.PrintPbSb(discipline.DisciplineCode, dr["ResultQuality"].ToString(), (int)dr["Code"], (int)dr["Result"], (int)dr["PB"], (int)dr["SB"]);
                sw.WriteLine("  <td align=\"center\">" + resultQuality + "</td>");
                sw.WriteLine("  <td align=\"center\">" + PrintHelper.PrintPoints(dr) + "</td>");

                sw.WriteLine("</tr>");

                rowCount += 1;
            }

            #endregion

            #region Not-ranked performances

            foreach (DataRow dr in dtPerformances.Select("Rank = 0 AND Code = 0", "Code, Rank"))
            {
                PrintHelper.PrintRowHeader(sw, rowCount);

                // Rank
                sw.WriteLine("  <td align=\"center\"></td>");
                sw.WriteLine("  <td align=\"center\">" + PrintHelper.PrintStartNumber(dr) + "</td>");

                // Flag, name, birthdate, club/country
                sw.WriteLine("  <td align=\"center\">" + PrintHelper.PrintFlagImage(dr) + "</td>");
                sw.WriteLine("  <td>" + PrintHelper.PrintName(dr) + "</td>");
                sw.WriteLine("  <td align=\"center\">" + PrintHelper.PrintBirthdate(Convert.ToDateTime(dr["BirthDate"])) + "</td>");
                sw.WriteLine("  <td>" + PrintHelper.PrintClubCountry(Globals.ActiveCompetition.ClubsCountries, dr) + "</td>");

                // Result
                sw.WriteLine("  <td align=\"center\"><b>" + PrintHelper.PrintResultWithCode(Convert.ToInt32(dr["Code"]), dr["Result"].ToString(), discipline) + "</b></td>");
                sw.WriteLine("  <td align=\"center\"></td>");
                sw.WriteLine("  <td align=\"center\"></td>");

                sw.WriteLine("</tr>");

                rowCount += 1;
            }

            #endregion

            sw.WriteLine("</table>");

            #region Ext. texts for performances

            DataTable dtExtTexts = ExtTextsHelper.ExtTextsDataTable(discipline);
            if (dtExtTexts.Rows.Count > 0)
            {
                sw.WriteLine("<hr>");

                sw.WriteLine("<table class=\"extra\">");
                sw.WriteLine("<tr>");
                sw.WriteLine("  <td width=\"30\"></td>");
                sw.WriteLine("  <td width=\"30\"></td>");
                sw.WriteLine("  <td width=\"120\">       </td>");
                foreach (string strHeight in discipline.Params.Split(','))
                {
                    string myValue = strHeight;

                    if (myValue.Contains('_'))
                        myValue = "R" + myValue.Split('_')[1];

                    sw.WriteLine("  <td width=\"30\" align=\"center\"><b>" + myValue + "</b></td> ");
                }
                sw.WriteLine("</tr>");

                foreach (DataRow dr in dtPerformances.Select("Rank > 0", "Rank"))
                {
                    DataRow[] drExtText = dtExtTexts.Select("PerformanceId = " + dr["ID"]);
                    sw.WriteLine("<tr>");
                    sw.WriteLine("  <td align=\"center\">" + PrintHelper.PrintRank(dr) + "</td>");
                    sw.WriteLine("  <td align=\"center\">" + PrintHelper.PrintStartNumber(dr) + "</td>");
                    sw.WriteLine("  <td>" + PrintHelper.PrintName(dr) + "</td>");
                    try
                    {
                        foreach (string strHeight in discipline.Params.Split(','))
                        {
                            if (drExtText[0][strHeight] == DBNull.Value)
                                sw.WriteLine("  <td></td>");
                            else
                                sw.WriteLine("  <td align=\"center\">" + PrintHelper.PrintResult(drExtText[0][strHeight].ToString(), discipline.DisciplineCode) + "</td>");
                        }
                    }
                    catch { }
                    sw.WriteLine("</tr>");
                }

                foreach (DataRow dr in dtPerformances.Select("Rank = 0", "Rank"))
                {
                    DataRow[] drExtText = dtExtTexts.Select("PerformanceId = " + dr["ID"]);
                    sw.WriteLine("<tr>");
                    sw.WriteLine("  <td align=\"center\"></td>");
                    sw.WriteLine("  <td align=\"center\">" + PrintHelper.PrintStartNumber(dr) + "</td>");
                    sw.WriteLine("  <td>" + PrintHelper.PrintName(dr) + "</td>");
                    try
                    {
                        foreach (string strHeight in discipline.Params.Split(','))
                        {
                            if (drExtText[0][strHeight] == DBNull.Value)
                                sw.WriteLine("  <td></td>");
                            else
                                sw.WriteLine("  <td align=\"center\">" + PrintHelper.PrintResult(drExtText[0][strHeight].ToString(), discipline.DisciplineCode) + "</td>");
                        }
                    }
                    catch { }
                    sw.WriteLine("</tr>");
                }

                sw.WriteLine("</table>");
            }

            #endregion

            #region Ext. texts for discipline

            dtExtTexts = DatabaseHelper.GetExtTextsByDisciplineListIdActive(discipline.ID);
            if (dtExtTexts.Rows.Count > 0)
            {
                sw.WriteLine("<hr>");
                sw.WriteLine("<table class='extra'>");

                foreach (DataRow drExtText in dtExtTexts.Rows)
                {
                    sw.WriteLine("<tr>");
                    sw.WriteLine("  <td width=\"20\"></td>");
                    sw.WriteLine("  <td>" + drExtText["Text1"] + "</td>");
                    sw.WriteLine("</tr>");
                }

                sw.WriteLine("</table>");
            }

            #endregion

            #region Points table

            PointsHelper.GetPointsTable(discipline, sw);

            #endregion

        }

        #endregion

        #region HeaderFooter

        public static void ResultsHeader(StreamWriter sw)
        {
            HtmlHelper.PrintHtmlHead(sw, "AtletIS Výsledky");

            sw.WriteLine("<body>");

            HtmlHelper.PrintHeader(sw, "Výsledková listina / Results", Globals.ActiveCompetition);
        }

        public static void ResultsFooter(StreamWriter sw)
        {
            HtmlHelper.PrintFooter(sw);
            sw.WriteLine("</body>");
            sw.WriteLine("</html>");
        }

        #endregion

        #region Points

        public static void Points(DisciplineListEntity discipline)
        {
            string htmlFilePath = HtmlHelper.GetNewHtmlFileName("(B) " + discipline.Name);
            StreamWriter sw = new StreamWriter(htmlFilePath, false, Encoding.Default);

            try
            {
                ResultsHeader(sw);

                sw.WriteLine("<h3>" + discipline.Name.ToString() + "</h3>");
                PointsHelper.GetPointsTable(discipline, sw);

                ResultsFooter(sw);

                sw.Close();
                sw.Dispose();

                WordHelper.CreateWordFromHtml(htmlFilePath);
            }
            catch (Exception ex)
            {
                if (sw != null)
                {
                    sw.Close();
                    sw.Dispose();
                }

                ExceptionHelper.ShowErrorInfo(ex);
            }
        }

        #endregion

        /// <summary>
        /// Spraví update Rank v Performances podľa Result, Code
        /// </summary>
        public static void UpdatePerformances(DisciplineListEntity discipline)
        {
            string sOrderBy = string.Empty;

            switch(discipline.DisciplineCode)
            {
                case Globals.SprintCode:
                case Globals.LongRunCode:
                case Globals.MarathonCode:
                case Globals.PointsAsc:
                case Globals.Triathlon:
                    sOrderBy = "Result ASC";    
                    break;

                case Globals.ThrowsCode:
                case Globals.HorJumpCode:
                case Globals.VerJumpCode:
                case Globals.PointsDesc:
                    sOrderBy = "Result DESC";    
                    break;
            }

            DataTable dtPerformances = DatabaseHelper.GetPerformancesByDisciplineListId(discipline.ID);
            int rank = 1, prevResult = 0, prevRank = 0;
            foreach(DataRow dr in dtPerformances.Select("Result > 0 AND Code = 0", sOrderBy))
            {
                if (Convert.ToInt32(dr["Result"]) != prevResult)
                    dr["Rank"] = rank;
                else
                    dr["Rank"] = prevRank;

                taPerformances.Update(dr);
                
                prevRank = Convert.ToInt32(dr["Rank"]);
                prevResult = Convert.ToInt32(dr["Result"]);

                rank += 1;
            }

            foreach (DataRow dr in dtPerformances.Select("Result = 0 OR Code > 0"))
            {
                dr["Rank"] = 0;
                taPerformances.Update(dr);
            }
        }

        /// <summary>
        /// Kompletné výsledky
        /// </summary>
        public static void CompleteResults(TreeView tvDisciplines)
        {
            string htmlFilePath = HtmlHelper.GetNewHtmlFileName("Výsledky");

            StreamWriter sw = new StreamWriter(htmlFilePath, false, Encoding.Default);

            try
            {
                HtmlHelper.PrintHtmlHead(sw, "AtletIS Export");

                sw.WriteLine("<body>");

                HtmlHelper.PrintHeader(sw, "Výsledková listina / Results", Globals.ActiveCompetition);

                #region Cyklus

                foreach (TreeNode tnParent in tvDisciplines.Nodes)
                {
                    if (tnParent.Checked)
                    {
                        DataTable dtParentDiscipline = DatabaseHelper.GetDisciplineListById(Convert.ToInt32(tnParent.Name));

                        if (dtParentDiscipline.Rows.Count > 0)
                        {
                            DisciplineListEntity parentDiscipline = DisciplineListHelper.ConvertToEntity(dtParentDiscipline.Rows[0]);

                            switch (parentDiscipline.DisciplineCode)
                            {
                                // Behy (1, 2, 6)
                                case Globals.SprintCode:
                                case Globals.LongRunCode:
                                case Globals.MarathonCode:
                                case Globals.Triathlon:
                                    DataTable dtParentPerformances = DatabaseHelper.GetPerformancesByDisciplineListId(parentDiscipline.ID);
                                    if (dtParentPerformances.Rows.Count > 0)
                                    {
                                        // NErozdelena disciplina
                                        sw.WriteLine("<h3>" + parentDiscipline.Name + "</h3>");
                                        ResultsHelper.RunTable(sw, parentDiscipline);
                                    }
                                    else
                                    {
                                        // Rozdelena disciplina
                                        foreach (TreeNode tnChild in tnParent.Nodes)
                                        {
                                            if (tnChild.Checked)
                                                ResultsHelper.MultiRunTable(tnChild, sw);
                                        }
                                    }
                                    break;

                                // Vrhy (3)
                                case Globals.ThrowsCode:
                                    sw.WriteLine("<h3>" + parentDiscipline.Name + "</h3>");
                                    ResultsHelper.ThrowsTable(sw, parentDiscipline);
                                    break;

                                // Dialka, trojskok (4)
                                case Globals.HorJumpCode:
                                    sw.WriteLine("<h3>" + parentDiscipline.Name + "</h3>");
                                    ResultsHelper.HorJumpsTable(sw, parentDiscipline);
                                    break;

                                // Vyska, zrd (5)
                                case Globals.VerJumpCode:
                                    sw.WriteLine("<h3>" + parentDiscipline.Name + "</h3>");
                                    ResultsHelper.VerJumpsTable(sw, parentDiscipline);
                                    break;

                                case Globals.PointsAsc:
                                case Globals.PointsDesc:
                                    sw.WriteLine("<h3>" + parentDiscipline.Name + "</h3>");
                                    PointsHelper.GetPointsTable(parentDiscipline, sw);
                                    break;
                            }
                        }
                    }
                }

                #endregion

                HtmlHelper.PrintFooter(sw);

                sw.WriteLine("</body>");
                sw.WriteLine("</html>");

                sw.Close();
                sw.Dispose();

                WordHelper.CreateWordFromHtml(htmlFilePath);
            }
            catch (Exception ex)
            {
                if (sw != null)
                {
                    sw.Close();
                    sw.Dispose();

                    WordHelper.CreateWordFromHtml(htmlFilePath);
                }

                ExceptionHelper.ShowErrorInfo(ex);
            }
        }

    }
}
